package com.ckzp.demo;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.ckzp.core.ConfigUtil;
import com.ckzp.jfinal.base.JfinalCheck;
import com.ckzp.jfinal.interceptor.AuthInterceptor;
import com.ckzp.jfinal.interceptor.ReadonlyInterceptor;
import com.ckzp.jfinal.interceptor.TokenInterceptor;
import com.ckzp.jfinal.system.cache.SysCache;
import com.ckzp.jfinal.system.model.SysActivity;
import com.ckzp.jfinal.system.model.SysApp;
import com.ckzp.jfinal.system.model.SysCode;
import com.ckzp.jfinal.system.model.SysCodeColumn;
import com.ckzp.jfinal.system.model.SysConfig;
import com.ckzp.jfinal.system.model.SysData;
import com.ckzp.jfinal.system.model.SysDept;
import com.ckzp.jfinal.system.model.SysFile;
import com.ckzp.jfinal.system.model.SysIp;
import com.ckzp.jfinal.system.model.SysMenu;
import com.ckzp.jfinal.system.model.SysOnline;
import com.ckzp.jfinal.system.model.SysPost;
import com.ckzp.jfinal.system.model.SysRole;
import com.ckzp.jfinal.system.model.SysTask;
import com.ckzp.jfinal.system.model.SysType;
import com.ckzp.jfinal.system.model.SysTypeDetail;
import com.ckzp.jfinal.system.model.SysUser;
import com.ckzp.jfinal.system.model.SysWorklog;
import com.ckzp.jfinal.system.route.CommRoutes;
import com.ckzp.jfinal.system.route.SystemRoutes;
import com.ckzp.jfinal.system.util.SysTaskUtil;
import com.ckzp.jfinal.system.util.SysWorkLogUtil;
import com.ckzp.jfinal.test.model.TestDemo;
import com.ckzp.jfinal.test.model.TestTable;
import com.ckzp.jfinal.test.route.TestRoutes;
import com.ckzp.jfinal.weixin.model.WxMember;
import com.ckzp.jfinal.weixin.model.WxMessage;
import com.ckzp.jfinal.weixin.model.WxPay;
import com.ckzp.jfinal.weixin.model.WxTemplet;
import com.ckzp.jfinal.weixin.route.WeixinRoutes;
import com.ckzp.plugins.sms.model.SysVcode;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.druid.IDruidStatViewAuth;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.render.ViewType;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;

import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.server.handlers.DisallowedMethodsHandler;
import io.undertow.util.HttpString;

/**
 * Created by 51594 on 2022/7/27.
 */
public class DemoConfig extends JFinalConfig {

	public static void main(String[] args) {
		// jetty
		// JFinal.start("WebRoot", 80, "/", 5);

		// Undertow
		// Undertow 是为嵌入而生的 Web Server，web.xml 已被抛弃，所以无法通过 web.xml 配置 web 组件。
		UndertowServer undertow = UndertowServer.create(DemoConfig.class);
		undertow.configWeb(builder -> {
			builder.addFilterUrlMapping("jfinal", "/admin9527/*");

			builder.addFilter("UrlRewriteFilter", "org.tuckey.web.filters.urlrewrite.UrlRewriteFilter");
			builder.addFilterUrlMapping("UrlRewriteFilter", "/*");
			builder.addFilterInitParam("UrlRewriteFilter", "logLevel", "WARN");

			// // 配置 Filter
			// builder.addFilter("myFilter", "com.abc.MyFilter");
			// builder.addFilterUrlMapping("myFilter", "/*");
			// builder.addFilterInitParam("myFilter", "key", "value");
			//
			// // 配置 Servlet
			// builder.addServlet("myServlet", "com.abc.MyServlet");
			// builder.addServletMapping("myServlet", "*.do");
			// builder.addServletInitParam("myServlet", "key", "value");
			//
			// // 配置 WebSocket，MyWebSocket 需使用 ServerEndpoint 注解
			// builder.addWebSocketEndpoint("com.abc.MyWebSocket");
		});

		// undertow.onDeploy((classLoader, deploymentInfo) -> {
		//// deploymentInfo.insertFilterUrlMapping(0, "shiro", "/*",
		// DispatcherType.REQUEST);
		// for (FilterMappingInfo fm : deploymentInfo.getFilterMappings()) {
		// System.out.println(fm.getFilterName());
		// }
		// });

		// 禁用 HTTP TRACE / TRACK Methods
		undertow.onDeploy((classLoader, deploymentInfo) -> {
			deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() {

				@Override
				public HttpHandler wrap(HttpHandler handler) {
					HttpString[] disallowedHttpMethods = { HttpString.tryFromString("TRACE"),
							HttpString.tryFromString("TRACK") };
					return new DisallowedMethodsHandler(handler, disallowedHttpMethods);
				}
			});

			// 开启SSE支持(Server-sent Events)
			// deploymentInfo.getFilters().get("jfinal").setAsyncSupported(true);
		});

		undertow.start();
	}

	/**
	 * 最先执行 action 1
	 *
	 * @param con
	 */
	public void configConstant(Constants con) {
		// 检查配置文件是否存在
		JfinalCheck.checkConfig();
		// 开启开发模式
		con.setDevMode(ConfigUtil.DEBUG());
		// 配置视图类型，默认使用 jfinal enjoy 模板引擎
		con.setViewType(ViewType.JFINAL_TEMPLATE);
		con.setEncoding("UTF8");
		con.setJsonDatePattern("yyyy-MM-dd HH:mm");

		///////////////////////// 存放文件路经////////////////////////
		// con.setBaseDownloadPath(ConfigUtil.getProperty("FILE_SAVE_PATH"));
		con.setError404View("/WEB-INF/resource/pages/error/404.html");
		con.setError500View("/WEB-INF/resource/pages/error/500.html");
		con.setErrorView(400, "/WEB-INF/resource/pages/error/400.html");
	}

	/**
	 * 3 配置路由
	 *
	 * @param routes
	 */
	public void configRoute(Routes routes) {
		routes.add(new SystemRoutes());
		routes.add(new CommRoutes());
		routes.add(new WeixinRoutes());
		routes.add(new TestRoutes());
	}

	/**
	 * 5
	 *
	 * @param engine
	 */
	public void configEngine(Engine engine) {
		engine.setDevMode(true);
	}

	/**
	 * 4
	 *
	 * @param me
	 */
	public void configPlugin(Plugins me) {
		// database config
		String MYSQL_URL = ConfigUtil.getProperty("MYSQL_URL");
		String MYSQL_USERNAME = ConfigUtil.getProperty("MYSQL_USERNAME");
		String MYSQL_PWD = ConfigUtil.getProperty("MYSQL_PWD");
		DruidPlugin dp = new DruidPlugin(MYSQL_URL, MYSQL_USERNAME, MYSQL_PWD);
		/////////////////////////////////
		dp.addFilter(new StatFilter()); // sql监控
		dp.addFilter(new WallFilter()); // 防止sql注入
		WallFilter wall = new WallFilter();
		wall.setDbType("mysql"); // mysql
		dp.addFilter(wall);
		//////////////////////////////////////////////
		me.add(dp);
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
		me.add(arp);
		// /////////////////////////定时任务/////////////////////////////
		// if (ConfigUtil.isLinux()) {
		// me.add(MyCron4jPlugin.n());
		// }
		///////////////////////////// redis///////////////////////////////////
		RedisPlugin rp = new RedisPlugin("demo", "demo", 6379, 10000, "testabc");

		me.add(rp);
		//////////////////////////////////////////////////////////////////////////////////
		// /////////////////////////cache/////////////////////////////
		me.add(new EhCachePlugin());
		///////////////////////// 系统表/////////////////////////////
		arp.addMapping("sys_menu", "menu_id", SysMenu.class);
		arp.addMapping("sys_user", "emp_id", SysUser.class);
		arp.addMapping("sys_role", "role_id", SysRole.class);
		arp.addMapping("sys_type", "type_code", SysType.class);
		arp.addMapping("sys_type_detail", "d_id", SysTypeDetail.class);
		arp.addMapping("sys_department", "dept_id", SysDept.class);
		arp.addMapping("sys_worklog", "log_id", SysWorklog.class);
		arp.addMapping("sys_config", "cf_key", SysConfig.class);
		arp.addMapping("sys_code", "c_id", SysCode.class);
		arp.addMapping("sys_code_column", "cc_id", SysCodeColumn.class);
		arp.addMapping("sys_files", "file_id", SysFile.class);
		arp.addMapping("sys_data", "data_key", SysData.class);
		arp.addMapping("sys_online", "sess_id", SysOnline.class);
		arp.addMapping("sys_ip", "ids", SysIp.class);
		arp.addMapping("sys_task", "task_id", SysTask.class);
		arp.addMapping("sys_activity", "act_id", SysActivity.class);
		arp.addMapping("sys_vcode", "mphone", SysVcode.class);
		arp.addMapping("sys_post", "post_id", SysPost.class);
		arp.addMapping("sys_app", "aid", SysApp.class);

		arp.addMapping("test_table", "test_id", TestTable.class);
		arp.addMapping("test_table", "test_id", TestDemo.class);
		// /////////////////////////微信/////////////////////////////
		arp.addMapping("wx_member", "mem_id", WxMember.class);
		arp.addMapping("wx_message", "msg_id", WxMessage.class);
		arp.addMapping("wx_pay", "pay_id", WxPay.class);
		arp.addMapping("wx_templet", "temp_id", WxTemplet.class);
	}

	/**
	 * 2
	 *
	 * @param interceptors
	 */
	public void configInterceptor(Interceptors interceptors) {
		// 验证权限
		interceptors.add(new AuthInterceptor());

		// 只读
		if (ConfigUtil.READONLY())
			interceptors.addGlobalActionInterceptor(new ReadonlyInterceptor());

		// 表单token验证拦截器
		interceptors.addGlobalActionInterceptor(new TokenInterceptor());
	}

	/**
	 * 6
	 *
	 * @param handlers
	 */
	public void configHandler(Handlers handlers) {
		///////////////////////// druid配置////////////////////////////////////////////
		DruidStatViewHandler dvh = new DruidStatViewHandler("/admin9527/druid", new IDruidStatViewAuth() {
			public boolean isPermitted(HttpServletRequest request) {
				return true;
			}
		});
		handlers.add(dvh);
		///////////////////////////////////////////////////////////////////////
	}

	/**
	 * 7 统启动完成后回调
	 */

	public void onStart() {
		if (ConfigUtil.DEBUG()) {
			System.out.println("-------------VISIT----" + ConfigUtil.getFullWebAdminLoginPath() + "------------------");
		}
		// 加载数据库配置的定时任务
		SysTaskUtil.n().initAllTask();
	}

	/**
	 * 8 系统关闭之前回调
	 */

	public void onStop() {
		// 关闭系统时，需要同步日志写入
		SysWorkLogUtil.n().scyWorkLog();
		SysTaskUtil.n().closeAllTask();
		SysCache.scyCache();
		// System.out.println("-------------end----------------------");
	}

}
